#include"../Log/zlog.h"
#include <ctime>
#include <ratio>
#include <chrono>
using namespace zlog;

void bench(const string& logger_name,size_t thread_count,size_t msg_count,size_t msg_len)
{
    //1.获取日志器
    Logger::ptr logger = getLogger(logger_name);
    if(logger.get() == nullptr)
      return;
    cout << "测试日志:" << msg_count << "条  " << "总大小:" << (msg_count*msg_len)/1024 << "KB" << endl;
    //2.组织指定长度的日志消息
    string msg(msg_len-1,'A'); //少一个字节是为了给末尾到时添加换行
    //3.创建指定数量的线程
    vector<thread> threads;
    vector<double> cost_array(thread_count);
    size_t msg_per_thread = msg_count / thread_count;//总日志数量 / 线程数量 = 每个线程要输出的日志数量
    for(int i = 0 ; i < thread_count ; i++)
    {
        threads.emplace_back([&,i](){
            //4.线程内部开始计时
            auto start = std::chrono::high_resolution_clock::now();
            //5.开始循环写日志
            for(int j = 0 ; j < msg_per_thread ; j++)
              logger->fatal("%s",msg.c_str());
            //6.线程函数内部结束计时
            auto end = std::chrono::high_resolution_clock::now();
            std::chrono::duration<double> cost = end - start;
            cost_array[i] = cost.count();
            cout << "线程" << i << ": " << "\t输出数量: " << msg_per_thread << ",耗时: " << cost.count() << "s" << endl; 
        });
    }
    for(int i = 0 ; i < thread_count ; i++)
       threads[i].join();
    //7.计算总耗时:在多线程中每个线程都会耗时,但线程是并发处理的,因此耗时最高的那个才是总时间
    double max_cost = cost_array[0];
    for(int i = 0 ; i < thread_count ; i ++)
      max_cost = max_cost < cost_array[i] ? cost_array[i] : max_cost;
    size_t msg_per_sec = msg_count / max_cost; //每秒输出日志数量
    size_t size_per_sec = (msg_count*msg_len) / (max_cost*1024); //每秒输出日志大小,单位KB
     //8.输出打印
     cout << "总耗时: " << max_cost << endl;
     cout << "每秒输出日志数量:" << msg_per_sec <<"条" << endl;
     cout << "每秒输出日志大小:" << size_per_sec << "KB" << endl;
}

void sync_bench()
{
    unique_ptr<LoggerBuilder> builder(new GlobalLoggerBuilder());
    builder->bulidLoggerName("sync_logger");
    builder->buildFormatter("[%d{%H:%M:%S}][%p]%T%m%n");
    builder->bulidLoggerType(LoggerType::TYPE_SYNC);
    builder->buildSink<FileLogSink>("./logfile/sync.log");
    builder->build();
    std::cout << "------------------- 同步日志器 单线程 ------------------- " << std::endl;
    bench("sync_logger",1,1000000,100);
    std::cout << "------------------- 同步日志器 多线程 ------------------- " << std::endl;
    bench("sync_logger",3,1000000,100);
}

void async_bench()
{
    unique_ptr<LoggerBuilder> builder(new GlobalLoggerBuilder());
    builder->bulidLoggerName("async_logger");
    builder->buildFormatter("[%d{%H:%M:%S}][%p]%T%m%n");
    builder->bulidLoggerType(LoggerType::TYPE_ASYNC);
    builder->buildSink<FileLogSink>("./logfile/async.log");
    builder->buildEnableUnSafeAsync();
    builder->build();
    std::cout << "----------------异步日志非安全模式单线程--------------------"<<  std::endl;
    bench("async_logger",1,1000000,100);
    std::cout << "----------------异步日志非安全模式多线程--------------------"<<  std::endl;
    bench("async_logger",7,1000000,100);
}


int main()
{
    async_bench();
    return 0;
}